/* * Copyright 2011 Stefan Partusch * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.spartusch.nasfvi.client; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.JsArrayMixed; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.json.client.JSONArray; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.ui.Anchor; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.InlineLabel; import com.google.gwt.user.client.ui.Tree; import com.google.gwt.user.client.ui.TreeItem; import com.google.gwt.user.client.ui.Widget; /** * Widget to visualize {@link NResponse} objects. * @author Stefan Partusch * */ public class NResponseWidget extends Composite { interface MyUiBinder extends UiBinder<Widget, NResponseWidget> {} private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class); /** * Labels to use when creating {@link * com.google.gwt.user.client.ui.TreeItem TreeItems} for the analyses. * The dimensions resemble the position of each subtree in the server's * response. If a label is null the text content of the subtree's first * child is used as a label. */ private static final String[][] LABELS = { {"Verbinformationen", "Felderstruktur", "Semantik"}, {"Vorfeld", "Mittelfeld"}, {null}, // label of each phrase {"Formmerkmale", "Token"}, {null} // label of each token }; @UiField InlineLabel query; @UiField InlineLabel similQuery; @UiField InlineLabel hits; @UiField InlineLabel fields; @UiField InlineLabel answer; @UiField Anchor link; @UiField Tree analysisReq; @UiField Tree analysisAns; /** HistoryStateSetter to use for setting the offset value. */ private HistoryStateSetter stateSetter; /** Offset to set when the "more" link is clicked. */ private int nextOffset; /** * Creates a visual representation of the response. This widget includes * a link to request more results. This is achieved through * <code>stateSetter</code>. * @param response Response to visualize * @param stateSetter HistoryStateSetter to use for setting new * offset values */ public NResponseWidget(final NResponse response, final HistoryStateSetter stateSetter) { this.stateSetter = stateSetter; if (response.isAggregated()) { nextOffset = response.getOffset() + 5; } else { nextOffset = response.getOffset() + 1; } initWidget(uiBinder.createAndBindUi(this)); answer.setText(response.getAnswer()); query.setText(response.getQuery()); hits.setText(String.valueOf(response.getHits())); if (response.getFields().length() == 0) { fields.setText("keine"); link.setVisible(false); } else { fields.setText(response.getFields().toString()); link.setVisible(nextOffset < response.getHits()); } if (response.getSimilarityQuery().isEmpty()) { similQuery.setText("keine"); } else { similQuery.setText(response.getSimilarityQuery()); } analysisReq.addItem(getAnalysis(response.getAnalysisRequest(), "Analyse der Anfrage")); analysisAns.addItem(getAnalysis(response.getAnalysisAnswer(), "Analyse der Antwort")); } @UiHandler("link") protected final void nextResult(final ClickEvent event) { stateSetter.setHistoryState(null, nextOffset); } /** * Creates and returns the visual representation of an analysis. * @param data Data of the analysis * @param text Label to set for the analysis * @return Visual representation of <code>data</code> */ private TreeItem getAnalysis(final JsArrayMixed data, final String text) { TreeItem root = getSubtree(new JSONArray(data), 0); root.setText(text); return root; } /** * Creates and returns a visual representation for a subtree. * @param data Data of the subtree * @param depth Depth of the subtree in the analysis * @return Visual representation of <code>data</code> */ private TreeItem getSubtree(final JSONArray data, final int depth) { TreeItem root = new TreeItem(); int subtrees = 0; for (int i = 0; i < data.size(); i++) { JSONArray array = data.get(i).isArray(); if (array == null) { // just a string root.addItem(data.get(i).isString().stringValue()); } else if (array.size() == 1 && array.get(0).isString() != null) { // array with a single string as an element root.addItem(array.get(0).isString().stringValue()); subtrees++; } else { // arrays TreeItem item = getSubtree(array, depth + 1); int x = (depth < LABELS.length) ? depth : LABELS.length - 2; int y = (subtrees < LABELS[x].length) ? subtrees : LABELS[x].length - 1; String label = LABELS[x][y]; if (label == null && item.getChildCount() > 0) { TreeItem first = item.getChild(0); label = first.getText(); item.removeItem(first); } item.setText(label); root.addItem(item); subtrees++; } } return root; } }